package com.voucher.controller;

import com.voucher.dao.DesEncryptUtil;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class xialaids {


    public static void main(String[] args) {
        String loginUrl = "http://222.177.166.226:28080/login.jsp";
        String username = "36363";
        String password = "363636";
        String fdId = "19517a30a83d3d651df06894576952a7";
        String savePath = "D://file.docx";

        CookieStore cookieStore = new BasicCookieStore();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore)
                .setRedirectStrategy(new LaxRedirectStrategy()) // 启用自动重定向
                .build();

        HttpClientContext context = HttpClientContext.create();
        context.setCookieStore(cookieStore);
        System.out.println("===== 开始登录 ====");
        System.out.println(context);
        System.out.println(context.getRedirectLocations());
        try {
            // === 1. 登录 ===
            HttpPost loginPost = new HttpPost(loginUrl);
            List<BasicNameValuePair> loginParams = new ArrayList<>();
            loginParams.add(new BasicNameValuePair("j_username", username));

            // 加密密码并打印（验证加密逻辑）
            String encryptedPassword = DesEncryptUtil.encrypt(password);
            System.out.println("[DEBUG] 加密后的密码: " + encryptedPassword);
            loginParams.add(new BasicNameValuePair("j_password", encryptedPassword));

            loginPost.setEntity(new UrlEncodedFormEntity(loginParams, StandardCharsets.UTF_8));

            // 执行登录（自动处理重定向）
            try (CloseableHttpResponse loginResponse = httpClient.execute(loginPost, context)) {
                int loginStatusCode = loginResponse.getStatusLine().getStatusCode();
                System.out.println("登录状态码: " + loginStatusCode);

                // 获取最终重定向后的 URL
                URI finalUri = context.getRedirectLocations()==null ? loginPost.getURI() : context.getRedirectLocations().get(0);
                String finalUrl = finalUri.toString();
                System.out.println("最终登录 URL: " + finalUrl);

                if (finalUrl.contains("login.jsp")) {
                    String responseBody = EntityUtils.toString(loginResponse.getEntity());
                    System.out.println("登录失败响应内容: " + responseBody);
                    throw new RuntimeException("登录失败，请检查账号密码或加密逻辑");
                }
            }

            // === 2. 打印 Cookies 并验证作用域 ===
            System.out.println("===== 登录后的 Cookies =====");
            cookieStore.getCookies().forEach(c ->
                    System.out.println(c.getName() + "=" + c.getValue() + "; Domain=" + c.getDomain() + "; Path=" + c.getPath()));

            // === 3. 强制设置 Cookie 作用域（修复服务端错误配置）===
//            cookieStore.getCookies().stream()
//                    .filter(c -> "JSESSIONID".equals(c.getName()))
//                    .findFirst()
//                    .ifPresent(jsession -> {
//                        BasicCookie newCookie = new BasicCookie(jsession);
//                        newCookie.setDomain("222.177.166.226"); // 确保 Domain 正确
//                        newCookie.setPath("/");
//                        cookieStore.addCookie(newCookie);
//                    });

            // === 4. 验证会话有效性 ===
            HttpGet validateRequest = new HttpGet("http://222.177.166.226:28080/user/profile");
            try (CloseableHttpResponse validateResponse = httpClient.execute(validateRequest, context)) {
                String validateContent = EntityUtils.toString(validateResponse.getEntity());
                if (validateContent.contains("SessionExpireTip")) {
                    throw new RuntimeException("会话验证失败，Cookie 无效");
                }
                System.out.println("会话验证成功");
            }

            // === 5. 构建下载请求 ===
            String downloadUrl = "http://222.177.166.226:28080/sys/attachment/sys_att_main/sysAttMain.do"
                    + "?method=download"
                    + "&fdId=" + URLEncoder.encode(fdId, "UTF-8")
                    + "&downloadType=manual"
                    + "&downloadFlag=" + System.currentTimeMillis();

            HttpGet httpGet = new HttpGet(downloadUrl);
            httpGet.setHeader("Referer", "http://222.177.166.226:28080/main.do");
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

            // === 6. 执行下载并处理重定向 ===
            try (CloseableHttpResponse downloadResponse = httpClient.execute(httpGet, context)) {
                int statusCode = downloadResponse.getStatusLine().getStatusCode();
                System.out.println("下载响应码: " + statusCode);

                // 处理重定向
                if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY || statusCode == HttpStatus.SC_MOVED_PERMANENTLY) {
                    String redirectUrl = downloadResponse.getFirstHeader(HttpHeaders.LOCATION).getValue();
                    System.out.println("重定向至: " + redirectUrl);
                    httpGet = new HttpGet(redirectUrl);
                    downloadResponse.close();
                    try (CloseableHttpResponse finalResponse = httpClient.execute(httpGet, context)) {
                        saveFile(finalResponse, savePath);
                    }
                } else {
                    saveFile(downloadResponse, savePath);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void saveFile(HttpResponse response, String savePath) throws Exception {
        Header contentType = response.getFirstHeader(HttpHeaders.CONTENT_TYPE);
        if (contentType != null && contentType.getValue().contains("application/octet-stream")) {
            try (InputStream is = response.getEntity().getContent();
                 FileOutputStream fos = new FileOutputStream(savePath)) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                }
                System.out.println("文件下载成功: " + savePath);
            }
        } else {
            String errorContent = EntityUtils.toString(response.getEntity());
            System.out.println("下载失败，响应内容: " + errorContent);
            throw new RuntimeException("下载失败，非文件内容");
        }
    }

}